#!/bin/bash
set -e
# -------------------------------------------------------------------------------
# Filename:     run-container-dev.sh
# Update:       2025/02/06
# Description:  Run docker image for IDE with optional command execution.
# Example:
#   启动容器普通方式（带交互）：                ./run-container-dev.sh
#   启动容器普通方式（不带交互）：              ./run-container-dev.sh --non-interactive
#   如启动容器后需要执行某个脚本（带交互）：     ./run-container-dev.sh --cmd "/path/to/script.sh"
#   如启动容器后需要执行某个脚本（不带交互）：   ./run-container-dev.sh --cmd "/path/to/script.sh" --non-interactive
#   如需要传递复杂命令时可使用引号包裹：         ./run-container-dev.sh --cmd "script.sh --arg1 value1 && echo 'Done'"
#   如需要保持服务运行，可在命令中使用nohup或&： ./run-container-dev.sh --cmd "nohup /path/to/script.sh > log.txt 2>&1 &"
# Depends:      container-${PATH_WORK}-${VERSION}-${Owner}
# Notes:
# -------------------------------------------------------------------------------
# 启动方式说明:
# [方式1] 普通交互模式 - 启动容器并进入Bash终端
#   示例: ./run-container-dev.sh
#   特点:
#   - 启动容器后自动进入交互式终端
#   - 适合手动调试和开发操作
#   - 默认挂载共享目录和数据目录
#
# [方式2] 命令执行模式 - 启动容器后执行指定命令
#   示例: ./run-container-dev.sh --cmd "/path/to/script.sh"
#   特点:
#   - 执行命令后保留容器运行（除非命令包含退出操作）
#   - 适合自动化部署/服务启动
#   - 可结合--non-interactive参数禁用后续交互
#
# 通用参数:
#   --cmd "command"        指定容器启动后执行的命令（支持完整shell语法）
#   --non-interactive      禁用交互式终端（仅执行命令）
# -------------------------------------------------------------------------------
# Source env
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
source "${SCRIPT_DIR}/env.sh"

# 初始化变量
EXECUTE_CMD=""
INTERACTIVE=true

###### 参数解析 ######
while [[ $# -gt 0 ]]; do
    case "$1" in
        --cmd)
            EXECUTE_CMD="$2"
            shift 2
            ;;
        --non-interactive)
            INTERACTIVE=false
            shift
            ;;
        *)
            echo "未知参数: $1"
            exit 1
            ;;
    esac
done

MY_CONTAINER_NEW="${MY_CONTAINER}"

###### 环境配置 ######
HOST_SHARE_PATH=$(realpath "${SCRIPT_DIR}/../")
CONTAINER_SHARE_PATH="/home/share"
HOST_DATA_PATH="/data"
CONTAINER_DATA_PATH="/data"

##########################################################
# 颜色检查
if [ -z "${red}" ] || [ -z "${none}" ]; then
    echo "ERROR: 颜色变量未正确加载，请检查env.sh文件"
    exit 1
fi

# 检查Docker镜像
if ! docker inspect --type=image "${NAME_IMAGE}" &>/dev/null; then
    echo -e "${red}ERROR: 镜像(${NAME_IMAGE})不存在! ${none}"
    exit 1
fi

# 容器状态检查
CONTAINER_EXISTS=$(docker ps -aq --filter "name=^/${MY_CONTAINER_NEW}$")

# 打印信息
echo "容器ID: $CONTAINER_EXISTS"
echo "镜像名称: $NAME_IMAGE"
echo "容器名称: $MY_CONTAINER_NEW"
echo "共享目录(HOST->CONTAINER): $HOST_SHARE_PATH ---> $CONTAINER_SHARE_PATH"
echo "数据目录(HOST->CONTAINER): $HOST_DATA_PATH ---> $CONTAINER_DATA_PATH"

# 启动/创建容器
if [ -z "${CONTAINER_EXISTS}" ]; then
    for dev in /dev/cambricon_ctl /dev/cambricon_ipcm0; do
        [ ! -e "${dev}" ] && echo -e "${yellow}WARNING: 设备文件 ${dev} 不存在! ${none}"
    done

    # 构建Docker命令
    DOCKER_CMD=(
        docker run
        --name "${MY_CONTAINER_NEW}"
        --detach
        --privileged
        --net=host
        --ipc=host
        --pid=host
        -v /usr/bin/cnmon:/usr/bin/cnmon:ro
        -v /sys/kernel/debug:/sys/kernel/debug:rw
        -v "${HOST_SHARE_PATH}:${CONTAINER_SHARE_PATH}:rw"
        -v "${HOST_DATA_PATH}:${CONTAINER_DATA_PATH}:rw"
        -p 8888:8888/tcp
        -w "${CONTAINER_SHARE_PATH}"
    )

    # X11支持
    if [ -n "${DISPLAY}" ] && [ -S /tmp/.X11-unix/X0 ]; then
        DOCKER_CMD+=(
            -e DISPLAY="unix${DISPLAY}"
            -v /tmp/.X11-unix:/tmp/.X11-unix:rw
        )
    fi

    # 设备挂载
    DOCKER_CMD+=(
        --device /dev/cambricon_ctl
        --device /dev/cambricon_ipcm0
        "${NAME_IMAGE}"
        tail -f /dev/null
    )

    # 执行创建命令
    echo -e "${green}>>> 启动新容器...${none}"
    "${DOCKER_CMD[@]}"

    # 等待容器就绪
    echo -e "${cyan}>>> 等待容器初始化(5秒)...${none}"
    sleep 5
else
    # 启动已存在的容器
    echo -e "${green}>>> 启动已有容器...${none}"
    docker start "${MY_CONTAINER_NEW}" >/dev/null
fi

# 执行用户命令
if [ -n "${EXECUTE_CMD}" ]; then
    echo -e "${green}>>> 执行命令: ${EXECUTE_CMD} ${none}"
    # 根据交互模式选择参数
    if [ "${INTERACTIVE}" = true ]; then
        DOCKER_EXEC_OPTS="-it"
    else
        DOCKER_EXEC_OPTS="-i"
    fi
    docker exec ${DOCKER_EXEC_OPTS} \
        --workdir "${CONTAINER_SHARE_PATH}" \
        "${MY_CONTAINER_NEW}" \
        bash -c "${EXECUTE_CMD}"
fi

# 交互模式
if [ "${INTERACTIVE}" = true ]; then
    echo -e "${green}>>> 进入交互终端...${none}"
    docker exec -it \
        --user root \
        "${MY_CONTAINER_NEW}" \
        /bin/bash -c "cd ${CONTAINER_SHARE_PATH} && cat /etc/motd && exec /bin/bash"
fi
